using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using ValidationFramework;
using ValidationRuleWriter.Properties;

namespace ValidationRuleWriter
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void browseButton_Click(object sender, EventArgs e)
        {
            using (var openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "dll files (*.dll)|*.dll";
                var dialogResult = openFileDialog.ShowDialog(this);
                if (dialogResult == DialogResult.OK)
                {
                    pathComboBox.Text = openFileDialog.FileName;
                    pathComboBox.AddRememberedValue(pathComboBox.Text);
                }
            }
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            if (!File.Exists(pathComboBox.Text))
            {
                MessageBox.Show("Invalid File Path.");
            }
            else
            {
                resultsTextBox.Clear();
                try
                {
                    var assembly = Assembly.LoadFrom(pathComboBox.Text);
                    var typeDescriptors = RuleDescriber.GetPropertyRules(assembly);
   var typeStringBuilder = new StringBuilder("\r\n\r\nTypes :\r\n===========================================================\r\n");
                      
                    if (typeDescriptors.Count == 0)
                    {
                        typeStringBuilder.Append("No property validation found.");
                    }
                    else
                    {
                       foreach (var typeDescriptor in typeDescriptors)
                        {
                            var type = Type.GetTypeFromHandle(typeDescriptor.RuntimeTypeHandle);
                            if (includeNamespacesCheckBox.Checked)
                            {
                                typeStringBuilder.AppendLine(string.Format("Class : {0}", type.FullName));
                                if (includeBaseClassCheckBox.Checked)
                                {
                                    typeStringBuilder.AppendLine(string.Format("Base Class : {0}", type.BaseType.FullName));
                                }
                            }
                            else
                            {
                                typeStringBuilder.AppendLine(string.Format("Class : {0}", type.Name));
                                if (includeBaseClassCheckBox.Checked)
                                {
                                    typeStringBuilder.AppendLine(string.Format("Base Class : {0}", type.BaseType.Name));
                                }
                            }
                            foreach (var propertyDescriptor in typeDescriptor.Properties)
                            {
                                typeStringBuilder.AppendLine(string.Format("\tProperty : {0}", propertyDescriptor.Name));
                                foreach (var rule in propertyDescriptor.Rules)
                                {
                                    typeStringBuilder.AppendLine(string.Format("\t\tRule : {0}", rule.RuleInterpretation));
                                }
                            }
                            typeStringBuilder.AppendLine("");
                            typeStringBuilder.AppendLine("");
                        }
                    }
                        resultsTextBox.Text = typeStringBuilder.ToString();
                    var methodDescriptors = RuleDescriber.GetMethodRules(assembly);
                var methodStringBuilder = new StringBuilder("\r\n\r\nMETHODS :\r\n===========================================================\r\n");

                    if (methodDescriptors.Count == 0)
                    {
                        methodStringBuilder.Append("No method validation found.");
                    }
                    else
                    {    
                        foreach (var methodDescriptor in methodDescriptors)
                        {
                            var methodBase = MethodInfo.GetMethodFromHandle(methodDescriptor.RuntimeMethodHandle);
                            var type = methodBase.DeclaringType;
                            methodStringBuilder.AppendLine(string.Format("Class : {0}, Method : {1}", type.FullName, methodBase.Name));
                            foreach (var parameterDescriptor in methodDescriptor.Parameters)
                            {
                                methodStringBuilder.AppendLine(string.Format("\tParameter : {0}", parameterDescriptor.Name));
                                foreach (var rule in parameterDescriptor.Rules)
                                {
                                    methodStringBuilder.AppendLine(string.Format("\t\tRule : {0}", rule.RuleInterpretation));
                                }
                            }
                            methodStringBuilder.AppendLine("");
                        }
                    }
                        resultsTextBox.Text += methodStringBuilder.ToString();
                }
                catch (FileLoadException fileLoadException)
                {
                    MessageBox.Show(string.Format("Could not load assembly due to FileLoadException. Exception Message: {0}", fileLoadException.Message));
                }
                catch (BadImageFormatException badImageFormatException)
                {
                    MessageBox.Show(string.Format("Could not load assembly due to BadImageFormatException. Exception Message: {0}", badImageFormatException.Message));
                }
            }
        }

        private void includeNamespacesCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            var settings = Settings.Default;
            settings.IncludeNamespaces = includeNamespacesCheckBox.Checked;
            settings.Save();
        }

        private void includeBaseClassCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            var settings = Settings.Default;
            settings.IncludeBaseClasses = includeBaseClassCheckBox.Checked;
            settings.Save();
        }
    }
}